<?php
namespace app\admin\controller;

use app\common\controller\Backend;
use think\Session;
use think\log;
use think\Db;
use think\Request;


/**
 * 仪器数据
 *
 * @icon fa fa-circle-o
 */
class Filedata extends Backend
{
    
    /**
     * Filedata模型对象
     */
    protected $model = null;
    protected $dataLimit = true;
    // 显示5个备注数据项
    protected $showFiveMemoColumn = false;
	// 批量上传一次最多可以上传几个数据文件
	protected $maxAllowedUploadFileNum = 10;
	


    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('Filedata');
        $this->view->assign("statusList", $this->model->getStatusList());
        $this->view->assign("stateList", $this->model->getStateList());

        $this->view->assign('showFiveMemoColumn', $this->showFiveMemoColumn);

    }
    
    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    public function myfn($b)
    {
        return(array( $b['id'] => $b));

    }
    public function test()
    {
        $row = Db::name('filedata')->where(['state' => '1', 'admin_id' => $this->auth->id])->field('id, instumentname as name, instumenttype as type')->select();

        var_dump($row);


        // $r = array_map("self::myfn", $row);
        $r = array_combine(array_map("current", $row), $row);
       // $r = array_map('current', $r);

        dump($r);
    }
    /*
    *   根据仪器类型获得该用户目前上传文件的信息
    *   1，该仪器类型，仅支持哪些文件后缀
    *   2，该仪器类型，设置的最大上传文件数，可使用最单空间
    *   3，该用户使用此仪器类型的数据：已上传文件数，已使用空间数
    *   4，该用户可使用此仪器类型的数据：剩余上传文件数，剩余可用空间。
    */
    public function getUploadFiledataInfo($type = "") 
    {
        
        $r = [
            'suffix' => [],
            'setting' => ['maxNum' => 0, 'maxSize' => 0],
            'used' => ['num' => 0, 'size' => 0],
            'remain' => ['num' => 0, 'size' => 0, 'formatSize' => 0]
        ];
       
        if(empty($type)) 
        {
            return $r;
        }

        // 
        $where = ['type' => $type];
        $data =  Db::name('instrument')->where($where)->field('suffix1, suffix2, suffix3, maxfilenum as maxNum, storagespace as maxSize')->find();

        if(empty($data)) 
        {
            return $r;
        }

        $data = array_map('strtolower', $data);
        $data = array_unique($data);
        $data = array_diff($data, ['-']);

        // 后缀
        for($i = 1; $i <= 3; $i++) 
        {
            $name = 'suffix'.$i;
            if(isset($data[$name]) && !empty($data[$name])) 
            {
                array_push($r['suffix'], $data[$name]);
            }  
        }
        if($r['suffix']) {
            $r['suffix'] = implode(",", $r['suffix']);
        };
        // 设置
        $r['setting']['maxNum'] = $data['maxNum'];
        $r['setting']['maxSize'] = $data['maxSize'] * 1024 * 1024;

        $where = [
            'admin_id' => $this->auth->id,
            'instumenttype' => $type,
            'state' => '1',
        ];        
        $row = Db::name('filedata')->where($where)->field('sum(filenum) as num, sum(filecapacity) as size ')->find();

        $r['used']['num'] = !empty($row['num']) ? $row['num'] : 0;
        $r['used']['size'] = !empty($row['size']) ? $row['size'] : 0;

        $r['remain']['num'] =  $r['setting']['maxNum'] - $r['used']['num'];
        $r['remain']['num'] = ($r['remain']['num'] < 0) ? 0 : $r['remain']['num'] ;

        $r['remain']['size'] =  $r['setting']['maxSize'] - $r['used']['size'];
        $r['remain']['size'] = ($r['remain']['size'] < 0) ? 0 : $r['remain']['size'] ;

        $r['remain']['formatSize'] =   ($r['remain']['size']) < 0 ? '0 B' :  format_bytes($r['remain']['size']);

        return $r;

    }

	/* 保存批量上传文件信息 */
    public function addimportfile()
    {        
        if ($this->request->isPost())
        {
            $params = $this->request->post("row/a");
			//dump($params);exit;

            if ($params)
            {
                $data = [];
				// 计算仪器数据文件的个数和总容量
				if(isset($params['fileattachmentsize']) && !empty($params['fileattachmentsize'])) {
					$_t = explode(",", $params['fileattachmentsize']);
					$data['filenum'] = count($_t);
					$data['filecapacity'] = array_sum($_t);

					$where = [
						'id' => $params['ids'],
						'state' => '1',
					];        
					$row = Db::name('filedata')->where($where)->field('filenum, filecapacity, datafiles')->find();
					
                    

                    $_datafiles_tmp = '';
                    if(!empty($row['datafiles'])) {
                         $_datafiles_tmp = $row['datafiles'];           
                    }  
                    $_datafiles_tmp .= ",".$params['datafiles'];
                    $_datafiles_arr = explode(",",  $_datafiles_tmp);
                    arsort($_datafiles_arr);                    

					$upData = [];
					$upData['filenum'] = $row['filenum'] + $data['filenum'];
					$upData['filecapacity'] = $row['filecapacity'] + $data['filecapacity'];
                    $upData['datafiles'] = implode(",", $_datafiles_arr);
					
					Db::name('filedata')->where($where)->update($upData);
					//$row->update($upData);
					//model('filedata')->Save($upData, $where);
					
					// 批量更新上传数据文件的状态
					if(isset($params['fileattachmentids']) && !empty($params['fileattachmentids'])) {
						$_w = [
							'id' => array('in', explode(',', $params['fileattachmentids'])),
						];
						model('fileattachment')->Save(['state' => 1, 'filedataid' => $params['ids']], $_w);
					}
					
					$this->success();
				}
                
               
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

    }

    /**
    *   批量导入数据文件
    */
    public function importfiledata() 
    {
        $request = Request::instance();
        $param = $request->param();

        if(isset($param['ids']) && !empty($param['ids'])) {
            $filedataId = (int) $param['ids'];
        }

        $filedataId = is_integer($filedataId) ? $filedataId : 0;
        $adminId = $this->auth->id;

        if(empty($filedataId) || empty($adminId))
        {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        // 根据记录ID，获取该记录对应的数据信息
        $where = ['id' => $filedataId,
                  'admin_id' => $adminId,
                  'state' => 1,
                 ];
        $row = Db::name('filedata')->where($where)->field('instumenttype as type, filenum, filecapacity as filesize')->find();
        
		if(empty($row))
		{
			$this->error(__('Parameter %s can not be empty', ''));
		}

        if(isset($row['type']) && !empty($row['type'])) 
        {
            $uploadInfo = $this->getUploadFiledataInfo($row['type']);
        }
		
        if($uploadInfo) {
            $uploadInfo['recordInfo'] = array(
                'ids' => $filedataId,
                'type' => $row['type'],
                'isuploadfiledata' => ( ($row['filenum'] > 0) && ($row['filesize'] > 0) ) ? true : false,
                'allowupload' => ($uploadInfo['remain']['num'] > 0 && $uploadInfo['remain']['size'] > 0 ) ? '': 'disabled="disabled"' ,
            );
        }  
       
	    // 限制本次最大允许上传数据文件的个数
		// 本次批量上传最大允许上传次数
		$allowUploadTimes = $this->maxAllowedUploadFileNum;
	    if($uploadInfo['remain']['num'] < $this->maxAllowedUploadFileNum) {
			$allowUploadTimes = $uploadInfo['remain']['num'];
		}
		
		$this->view->assign('allowUploadTimes', $allowUploadTimes);
		
        $this->view->assign('uploadInfo', $uploadInfo);
        //dump($uploadInfo);exit;

        return $this->view->fetch();
    }


    /*
    * 下载功能
    * 文件夹名=仪器名+序列号+日期
    */
    public function downloadzip($filename = array()) 
    {
        if(empty($filename) ) 
        {
            throw new Exception(__('No Data.'));
        }

      
        if (!class_exists('ZipArchive'))
        {
            throw new Exception(__('ZinArchive not install'));
        }
        
        // 创建临时下载目录        
        $ziptemppath = RUNTIME_PATH . 'filedata' . DS;        
        if( !file_exists($ziptemppath) ) {
            if(!mkdir($ziptemppath, 0777, true)) {
                throw new Exception(__('Download Template Path can not create.'));
            }
        }         
        // dump(FILEDATA_PATH);exit;

        foreach($filename as $k => $v) 
        {
            // 压缩文件名
            $downloadname = $v['downloadname'];    //_print($downloadname);exit;  
            $zipname = $ziptemppath.$downloadname;
            if(!touch($zipname)) {
                throw new Exception(__('Download template file can not touch.'));
            }

            $zip = new \ZipArchive;
            //新建zip压缩包
            $zip->open($zipname, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);

            //打包文件
            $files = $v['files'];

            foreach ($files as $file) {
                $tempurl = FILEDATA_PATH. $file['url'];
                $rempname = $file['name'];
                
                if(file_exists($tempurl)) {
                    $zip->addFile($tempurl, $rempname);
                }                 
            }
            $zip->close();            

            $filename = basename($zipname);
            $filename = urldecode($filename);

            //mb_http_output('UTF-8');
            header("Cache-Control: public"); 
            header("Expires:0");
            header("Cache-Component: must-revalidate, post-check=0, pre-check=0");
            header('Content-Type: pplication/zip');
            header('Content-Length: '. filesize($zipname)); //告诉浏览器，文件大小 
            header("Content-Description: File Transfer");              
            header('Content-disposition: attachment; filename="'.$filename.'"'); //文件名 
            header("Content-Transfer-Encoding: binary");       
            readfile($zipname);
        }
    }

    /**
    *   批量导出数据文件
    */
    public function exportfiledata() 
    {
        $request = Request::instance();
        $param = $request->param();

        if(isset($param['ids']) && !empty($param['ids'])) {
            $filedataId =  $param['ids'];
        }

        $filedataId = explode(",", $filedataId); //dump($filedataId);
        $filedataId = array_unique($filedataId);
        $adminId = $this->auth->id;          

        if(empty($filedataId) || empty($adminId))
        {
            $this->error(__('Parameter %s can not be empty', ''));
        }
		
		//echo $filedataId; echo $adminId;	
        $where = array(
            'admin_id' => $adminId,
            'id' => array('in', $filedataId),
            'state' => '1',
        );
        $field = 'id, instumentname, instumentsno, createtime';

        $filedatarow = Db::name('filedata')->where($where)->field($field)->select();

        if(empty($filedatarow)) {
           $this->error(__('Forbidden Visit')); 
        }

        //
        $downloadnamearrs = [];
        if($filedatarow)
        {
            foreach($filedatarow as $v) {
                $downloadname = $v['instumentname'].'-'.$v['instumentsno'].'-'.date('Ymd', $v['createtime']).'.zip';
                $downloadname = urlencode($downloadname);
                //echo $downloadname;exit;

                $downloadnamearrs[$v['id']] = array(
                    'downloadname' => $downloadname,
                    'files' => [],
                );
            }
        }
        unset($filedatarow);

        $where = array(
            'admin_id' => $adminId,
            'filedataid' => array('in', $filedataId),
            'state' => 1
        );
        $field = 'filedataid, originalname';

        $row = Db::name('fileattachment')->where($where)->distinct(true)->field('url')->field($field)->select();

       // dump($row);exit;
        if(empty($row)) {
            $this->error(__('No Upload Files')); 
        }
        
        if($row) {
            foreach($row as $v) {
                $downloadnamearrs[$v['filedataid']]['files'][] = array(
                    'name' => $v['originalname'],
                    'url' => $v['url'],
                );
            }
        }	
		unset($row);

        $this->downloadzip($downloadnamearrs);		
    }
    
    /**
     * 添加
     */
    public function add()
    {
        if ($this->request->isPost())
        {
            $params = $this->request->post("row/a");

            if ($params)
            {
                if ($this->dataLimit && $this->dataLimitFieldAutoFill)
                {
                    $params[$this->dataLimitField] = $this->auth->id;

                    $params['acount'] = Session::get('admin')['username'];

                    // 计算仪器数据文件的个数和总容量
                    if(isset($params['fileattachmentsize']) && !empty($params['fileattachmentsize'])) {
                        $_t = explode(",", $params['fileattachmentsize']);
                        $params['filenum'] = count($_t);
                        $params['filecapacity'] = array_sum($_t);

                        unset($params['fileattachmentsize']);

                        // 批量更新上传数据文件的状态
                        if(isset($params['fileattachmentids']) && !empty($params['fileattachmentids'])) {
                            $_w = [
                                'id' => array('in', explode(',', $params['fileattachmentids'])),
                            ];
                            model('fileattachment')->Save(['state' => 1], $_w);
                        }
                    }
                }
                try
                {
                    //是否采用模型验证
                    if ($this->modelValidate)
                    {
                        $name = basename(str_replace('\\', '/', get_class($this->model)));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
                        $this->model->validate($validate);
                    }
                    $result = $this->model->allowField(true)->save($params);
                    if ($result !== false)
                    {
                        $this->success();
                    }
                    else
                    {
                        $this->error($this->model->getError());
                    }
                }
                catch (\think\exception\PDOException $e)
                {
                    $this->error($e->getMessage());
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

        
        $this->view->assign('instrumentNames', $this->getAllInstrumentNames());
  

        return $this->view->fetch();
    }

    /**
     * 编辑
     */
    public function edit($ids = NULL)
    {
        $row = $this->model->get($ids);
        if (!$row)
            $this->error(__('No Results were found'));
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds))
        {
            if (!in_array($row[$this->dataLimitField], $adminIds))
            {
                $this->error(__('You have no permission'));
            }
        }
        if ($this->request->isPost())
        {
            $params = $this->request->post("row/a");
            if ($params)
            {
                try
                {
                    //是否采用模型验证
                    if ($this->modelValidate)
                    {
                        $name = basename(str_replace('\\', '/', get_class($this->model)));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate;
                        $row->validate($validate);
                    }
                    $result = $row->allowField(true)->save($params);
                    if ($result !== false)
                    {
                        $this->success();
                    }
                    else
                    {
                        $this->error($row->getError());
                    }
                }
                catch (\think\exception\PDOException $e)
                {
                    $this->error($e->getMessage());
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
		//_print($row->getData());exit;
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    // 获得所有的仪器名称（去重）
    protected function getAllInstrumentNames() {
        $list = \app\admin\model\Instrument::where('state',1)->column('title','id');
        if($list) {
            $list = array_unique($list);
        }

        if(is_array($list)) {
            return $list;
        } else {
            return [];
        }
    }


    /**
     * Selectpage搜索
     * 
     * @internal
     */
    public function insnames()
    {
        //return parent::selectpage();
        $province = $this->getAllInstrumentNames();

    
        $r = array();
        foreach($province as $k => $v) {
            array_push($r, ['id' => $v, 'name' => $v]);
        }

        $total = count($r);
         return json(['list' => $r, 'total' => $total]);
    }



    /**
     * 删除
     * 删除数据文件的同时，要删除相应的数据文件
     */
    public function del($ids = "")
    {
        if ($ids)
        {
            $pk = $this->model->getPk();
            $adminIds = $this->getDataLimitAdminIds();

            if (is_array($adminIds))
            {
                $count = $this->model->where($this->dataLimitField, 'in', $adminIds);
            }
            $list = $this->model->where($pk, 'in', $ids)->select();              

            $count = 0;
            foreach ($list as $k => $v)
            {                 
                $count += $v->delete();
            }

            
            if ($count)
            {   
                $data = ['filedataid' => 0, 'state' => 0];
                $db = Db::name('fileattachment');
                $db->where('filedataid', 'in', $ids)->update($data);   

                $this->success();
            }
            else
            {
                $this->error(__('No rows were deleted'));
            }
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }
}
